package com.quanyan.riding.service.impl;

import com.github.ltsopensource.core.json.JSON;
import com.quanyan.api.APIResponse;
import com.quanyan.api.enums.ApiResponseEnum;
import com.quanyan.redisCluster.utils.RedisConstants;
import com.quanyan.redisCluster.utils.RedisKey;
import com.quanyan.riding.component.cache.MyRedisTemplate;
import com.quanyan.riding.constans.Constans;
import com.quanyan.riding.entity.db.*;
import com.quanyan.riding.entity.vo.req.ReqJoinRidingBike;
import com.quanyan.riding.entity.vo.req.ReqUpdateBikePeopleLocation;
import com.quanyan.riding.entity.vo.resp.RespRidingBikeManager;
import com.quanyan.riding.entity.vo.resp.RespRidingCheckBike;
import com.quanyan.riding.entity.vo.resp.RespUpdateBikePeopleLocation;
import com.quanyan.riding.mapper.MyTbRidingRecordMapper;
import com.quanyan.riding.mapper.TbRidingBikeMapper;
import com.quanyan.riding.mapper.TbRidingBikePeopleMapper;
import com.quanyan.riding.mapper.TbUserMapper;
import com.quanyan.riding.service.RidingBikeService;
import com.quanyan.riding.util.CommonUtil;
import com.quanyan.riding.util.RunRidingEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author xian-guo
 * @email 498152332@qq.com
 * @date 2016/9/2.
 */
@Service("ridingBikeServiceImpl")
public class RidingBikeServiceImpl implements RidingBikeService {

    private static final Logger LOGGER = LoggerFactory.getLogger(RidingBikeServiceImpl.class);

    @Autowired
    private MyRedisTemplate myRedisTemplate;

    /**
     * 车队成员
     */
    @Autowired
    private TbRidingBikePeopleMapper tbRidingBikePeopleMapper;

    /**
     * 车队
     */
    @Autowired
    private TbRidingBikeMapper tbRidingBikeMapper;

    /**
     * 用户表
     */
    @Autowired
    private TbUserMapper tbUserMapper;

    /**
     * 自定义sql
     */
    @Autowired
    private MyTbRidingRecordMapper myTbRidingRecordMapper;

    /**
     * 查询用户创建的和加入的车队
     * @param userId
     * @return
     */
    @Override
    public APIResponse<List<RespRidingCheckBike>> getRidingBikeMessage(String userId) {
        TbRidingBikePeopleExample tbRidingBikePeopleExample=new TbRidingBikePeopleExample();
        tbRidingBikePeopleExample.createCriteria().andUserIdEqualTo(userId);
        //查询用户是否有加入或创建车队
        List<TbRidingBikePeople> tbRidingBikePeopleList=tbRidingBikePeopleMapper.selectByExample(tbRidingBikePeopleExample);
        if (tbRidingBikePeopleList.size()==0){
            return APIResponse.returnFail("该用户没有加入或创建车队");
        }
        List<RespRidingCheckBike> respRidingCheckBikeList=myTbRidingRecordMapper.getRidingBikeMsg(tbRidingBikePeopleList);
        LOGGER.debug("----------"+ JSON.toJSONString(respRidingCheckBikeList));
        return APIResponse.returnSuccess(respRidingCheckBikeList);
    }

    /**
     * 创建车队
     * @param userId
     * @return
     */
    @Override
    @Transactional
    public APIResponse createRidingBike(String userId,String longLat) {
        TbUserExample tbUserExample=new TbUserExample();
        tbUserExample.createCriteria().andUserIdEqualTo(userId).andUserTypeEqualTo(Constans.RIDINGTYPE);
        //查询是否非法用户id
        List<TbUser> tbRidingUserList=tbUserMapper.selectByExample(tbUserExample);
        if (tbRidingUserList.size()==0){//非法用户
            return APIResponse.returnFail(ApiResponseEnum.PERMISSION_DENIED);
        }
        //检查个人创建车队上限
        TbRidingBikeExample tbRidingBikeExample=new TbRidingBikeExample();
        tbRidingBikeExample.createCriteria().andUserIdEqualTo(userId);
        int countBike=tbRidingBikeMapper.countByExample(tbRidingBikeExample);
        if (countBike>=Constans.CREATE_BIKE_NUMBER){//每个人创建的车队最多为10个
            return APIResponse.returnFail(RunRidingEnum.OVER_BIKE_NUMBER_LIMIT);
        }
        //检查车队总数量是否达到上限
        int allCountNum=tbRidingBikeMapper.countByExample(new TbRidingBikeExample());
        if (allCountNum>=Constans.ALL_BIKE_NUMBER){//车队总数量超过上限
            Map<String,Object> paramMap =new HashMap<>();
            paramMap.put("bikeMember",1);
            Map<String,Object> commandMap=myTbRidingRecordMapper.getRidingBikeMinCreateTime(paramMap);
            if (null == commandMap){
                paramMap.remove("bikeMember");
                commandMap =myTbRidingRecordMapper.getRidingBikeMinCreateTime(paramMap);
            }
            String comm= (String) commandMap.get("bike_command");
            TbRidingBikeExample delTbRidingBike=new TbRidingBikeExample();
            delTbRidingBike.createCriteria().andBikeCommandEqualTo(comm);
            int delBike=tbRidingBikeMapper.deleteByExample(delTbRidingBike);
            TbRidingBikePeopleExample delTbRidingBikePeople =new TbRidingBikePeopleExample();
            delTbRidingBikePeople.createCriteria().andBikeCommandEqualTo(comm);
            int delBikePeople=tbRidingBikePeopleMapper.deleteByExample(delTbRidingBikePeople);
            LOGGER.debug("------删除车队---->>>>>>"+delBike+"------删除车队成员---->>>>"+delBikePeople);
        }
        //获取缓存中口令集合
        RedisKey key = new RedisKey(RedisConstants.RUN_RIDING_CACHE_PREFIX, Constans.GET_BIKE_COMMAND);
        List<Integer> commandList = (List<Integer>) myRedisTemplate.get(key);
        if (null == commandList){//redis数据丢失，可能导致出现重复口令
            commandList= CommonUtil.getRandomCommand(commandList);
            myRedisTemplate.set(key,commandList);
            LOGGER.error("-------redis数据丢失，可能导致出现重复口令----------------");
        }
        if (commandList.size()<= 0){//如果集合中口令没有了，说明车队口令的删除和回收出现问题，会导致出现重复口令的情况
            commandList=CommonUtil.getRandomCommand(commandList);
            myRedisTemplate.set(key,commandList);
            LOGGER.error("-------如果集合中口令没有了，说明车队口令的删除和回收出现问题，会导致出现重复口令的情况----------------");
        }
        String command=String.valueOf(commandList.remove(0));//获取车队口令
        myRedisTemplate.set(key,commandList);
        TbRidingBike tbRidingBike=new TbRidingBike();
        tbRidingBike.setUserId(userId);
        tbRidingBike.setBikeCommand(command);
        tbRidingBike.setBikeMember((byte) 1);
        tbRidingBike.setCreateTime(new Date());
        //插入新车队
        int createBike=tbRidingBikeMapper.insert(tbRidingBike);
        //插入车队成员表
        TbRidingBikePeople tbRidingBikePeople=new TbRidingBikePeople();
        tbRidingBikePeople.setUserId(userId);
        tbRidingBikePeople.setBikeCommand(command);
        tbRidingBikePeople.setPhotoUrl(tbRidingUserList.get(0).getPhotoUrl());
        tbRidingBikePeople.setUserLimit((byte) 1);
        tbRidingBikePeople.setLongLat(longLat);
        tbRidingBikePeople.setUserNick(tbRidingUserList.get(0).getUserNick());
        tbRidingBikePeople.setJoinTime(new Date());
        int insertPeople=tbRidingBikePeopleMapper.insert(tbRidingBikePeople);
        LOGGER.info("---------创建车队---->>>>"+createBike+"------插入车队人员表----->>>>>"+insertPeople);
        if (createBike>0 && insertPeople>0){
            return APIResponse.returnSuccess(command);
        }
        return APIResponse.returnFail("创建车队失败");
    }

    /**
     * 定时删除创建超过72小时的车队
     * @return
     */
    @Override
    @Transactional
    public void delRidingBike() {
        //先查询需要删除的车队口令
        List<Map<String,Object>> paramMapList=myTbRidingRecordMapper.recycleBikeCommand();
        //先删除车队用户信息
        int delPeople=myTbRidingRecordMapper.delRidingBikePeople();
        //再删除车队
        int delSucc=myTbRidingRecordMapper.delRidingBike();
        LOGGER.debug("删除超过72小时车队------>>>>>"+delSucc+"-----删除超过72小时车队成员------->>>>"+delPeople);
        //事务控制，所有的删除操作成功之后，回收车队口令
        RedisKey key = new RedisKey(RedisConstants.RUN_RIDING_CACHE_PREFIX, Constans.GET_BIKE_COMMAND);
        List<Integer> commandList = (List<Integer>) myRedisTemplate.get(key);
        if(paramMapList.size()==0){
            return;
        }
        for (Map<String,Object> map:paramMapList){
            commandList.add(Integer.valueOf((String) map.get("bike_command")));//回收车队口令
        }
        myRedisTemplate.set(key,commandList);
    }

    /**
     * 加入车队
     * @param reqJoinRidingBike
     * @return
     */
    @Override
    @Transactional
    public APIResponse<List<TbRidingBikePeople>> joinRidingBike(ReqJoinRidingBike reqJoinRidingBike) {
        TbUserExample tbUserExample=new TbUserExample();
        tbUserExample.createCriteria().andUserIdEqualTo(reqJoinRidingBike.getUserId()).andUserTypeEqualTo(Constans.RIDINGTYPE);
        List<TbUser> tbUserList=tbUserMapper.selectByExample(tbUserExample);
        if (tbUserList.size()==0){//非法用户
            return APIResponse.returnFail(ApiResponseEnum.PERMISSION_DENIED);
        }
        //不允许加入自己创建的车队，以及多次加入同一个车队
        TbRidingBikePeopleExample tbRidingBikePeopleExample=new TbRidingBikePeopleExample();
        tbRidingBikePeopleExample.createCriteria().andBikeCommandEqualTo(reqJoinRidingBike.getBikeCommand()).andUserIdEqualTo(reqJoinRidingBike.getUserId());
        List<TbRidingBikePeople> tbRidingBikePeopleList=tbRidingBikePeopleMapper.selectByExample(tbRidingBikePeopleExample);
        if (tbRidingBikePeopleList.size()>0){
            return APIResponse.returnFail("不允许多次加入同一个车队");
        }
        //让车队成员数量 + 1
        byte succ=this.addRidingBikeMember(reqJoinRidingBike);
        if (succ==1){
            return APIResponse.returnFail(ApiResponseEnum.PERMISSION_DENIED);
        }else if (succ==2){
            return APIResponse.returnFail("车队成员已满");
        }else if (succ==3){
            return APIResponse.returnFail("加入车队失败");
        }
        //插入车队成员信息
        TbUser tbUser=tbUserList.get(0);
        TbRidingBikePeople tbRidingBikePeople=new TbRidingBikePeople();
        tbRidingBikePeople.setUserId(reqJoinRidingBike.getUserId());
        tbRidingBikePeople.setUserNick(tbUser.getUserNick());
        tbRidingBikePeople.setJoinTime(new Date());
        tbRidingBikePeople.setLongLat(reqJoinRidingBike.getLongLat());
        tbRidingBikePeople.setUserLimit((byte) 0);
        tbRidingBikePeople.setBikeCommand(reqJoinRidingBike.getBikeCommand());
        tbRidingBikePeople.setPhotoUrl(tbUser.getPhotoUrl());
        int inser=tbRidingBikePeopleMapper.insert(tbRidingBikePeople);
        if (inser>0){//加入车队成功
            //查找车队所有成员信息
            TbRidingBikePeopleExample allTbRidingBikePeopleExample=new TbRidingBikePeopleExample();
            allTbRidingBikePeopleExample.createCriteria().andBikeCommandEqualTo(reqJoinRidingBike.getBikeCommand());
            List<TbRidingBikePeople> tbRidingBikePeoples=tbRidingBikePeopleMapper.selectByExample(allTbRidingBikePeopleExample);
            return APIResponse.returnSuccess(tbRidingBikePeoples);
        }else {
            return APIResponse.returnFail("加入车队失败");
        }
    }

    /**
     * 车队成员数量+1
     * @param reqJoinRidingBike
     * @return
     */
    private synchronized Byte addRidingBikeMember(ReqJoinRidingBike reqJoinRidingBike){
        TbRidingBikeExample tbRidingBikeExample=new TbRidingBikeExample();
        tbRidingBikeExample.createCriteria().andBikeCommandEqualTo(reqJoinRidingBike.getBikeCommand());
        List<TbRidingBike> tbRidingBikeList=tbRidingBikeMapper.selectByExample(tbRidingBikeExample);
        if (tbRidingBikeList.size()==0){
            return 1;
        }
        TbRidingBike tbRidingBike=tbRidingBikeList.get(0);
        int bikeMember=tbRidingBike.getBikeMember();
        if (bikeMember>=Constans.MAX_BIKE_MEMBER){//超过最大容量
            return 2;
        }
        tbRidingBike.setBikeMember((byte) (tbRidingBike.getBikeMember()+1));
        int update=tbRidingBikeMapper.updateByExample(tbRidingBike,tbRidingBikeExample);
        return update==0?(byte)3:(byte)4;
    }

    /**
     * 创建车队成功，加入车队
     * @param
     * @return
     */
    @Override
    public APIResponse<List<TbRidingBikePeople>> createBikeJoin(String command) {
        TbRidingBikePeopleExample tbRidingBikePeopleExample=new TbRidingBikePeopleExample();
        tbRidingBikePeopleExample.createCriteria().andBikeCommandEqualTo(command);
        List<TbRidingBikePeople> tbRidingBikePeopleList=tbRidingBikePeopleMapper.selectByExample(tbRidingBikePeopleExample);
        LOGGER.debug("----创建车队成功，加入车队----车队成员数量------"+tbRidingBikePeopleList.size());
        return APIResponse.returnSuccess(tbRidingBikePeopleList);
    }

    /**
     * 实时跟新车队成员位置
     * 备注：客户端处理xxx加入车队，根据userId即可
     * @param updateBikePeopleLocation
     * @return
     */
    @Override
    public APIResponse<List<RespUpdateBikePeopleLocation>> updateRidingBikePeopleLocation(ReqUpdateBikePeopleLocation updateBikePeopleLocation) {
        //跟新成员位置
        Map<String,Object> paramMap=new HashMap<>();
        paramMap.put("userId",updateBikePeopleLocation.getUserId());
        paramMap.put("command",updateBikePeopleLocation.getCommand());
        paramMap.put("longLat",updateBikePeopleLocation.getLongLat());
        int upSucc=myTbRidingRecordMapper.updateBikePeopleLocation(paramMap);
        //获取车队其他成员信息
        List<RespUpdateBikePeopleLocation> respUpdateList=myTbRidingRecordMapper.getBikePeopleLocation(paramMap);
        LOGGER.debug(upSucc+"<---跟新车队成员位置-----车队成员数量--->"+respUpdateList.size());
        return APIResponse.returnSuccess(respUpdateList);
    }

    /**
     * 车队管理
     * @param command
     * @return
     */
    @Override
    public APIResponse<RespRidingBikeManager> managerBikePerple(String command) {
        //查找车队公告
        TbRidingBikeExample tbRidingBikeExample=new TbRidingBikeExample();
        tbRidingBikeExample.createCriteria().andBikeCommandEqualTo(command);
        List<TbRidingBike> tbRidingBikeList=tbRidingBikeMapper.selectByExample(tbRidingBikeExample);
        if (tbRidingBikeList.size()==0){
            return APIResponse.returnFail("该口令无效");
        }
        TbRidingBike tbRidingBike=tbRidingBikeList.get(0);
        RespRidingBikeManager ridingBikeManager=new RespRidingBikeManager();
        ridingBikeManager.setPublicNotice(tbRidingBike.getBikeNotice());
        ridingBikeManager.setCommand(command);
        //查找车队成员信息
        TbRidingBikePeopleExample tbRidingBikePeopleExample=new TbRidingBikePeopleExample();
        tbRidingBikePeopleExample.createCriteria().andBikeCommandEqualTo(command);
        List<TbRidingBikePeople> tbRidingBikePeopleList=tbRidingBikePeopleMapper.selectByExample(tbRidingBikePeopleExample);
        if (tbRidingBikePeopleList.size()==0){
            return APIResponse.returnFail("无效车队");
        }
        ridingBikeManager.setTbRidingBikePeopleList(tbRidingBikePeopleList);
        return APIResponse.returnSuccess(ridingBikeManager);
    }

    /**
     * 退出车队
     * @param userId
     * @param command
     * @return
     */
    @Override
    @Transactional
    public APIResponse quitRidingBike(String userId,String command) {
        TbRidingBikePeopleExample tbRidingBikePeopleExample=new TbRidingBikePeopleExample();
        tbRidingBikePeopleExample.createCriteria().andBikeCommandEqualTo(command).andUserIdEqualTo(userId);
        List<TbRidingBikePeople> tbRidingBikePeopleList=tbRidingBikePeopleMapper.selectByExample(tbRidingBikePeopleExample);
        if (tbRidingBikePeopleList.size()==0){
            return APIResponse.returnFail("操作失败");
        }
        TbRidingBikePeople tbRidingBikePeople=tbRidingBikePeopleList.get(0);
        byte limit= tbRidingBikePeople.getUserLimit();
        int delPeo=0;
        int delBike=0;
        if (Constans.BIKE_CUSTOMER == limit){//普通成员
            delPeo=tbRidingBikePeopleMapper.deleteByExample(tbRidingBikePeopleExample);
            int num=myTbRidingRecordMapper.updateRidingBikePeople(command);//成员数量-1
            LOGGER.debug(num+"--成员数量---------退出车队，删除-----"+delPeo);
        }else if (Constans.BIKE_LEADER == limit){//车队创建者，则解散车队
            //先删除车队成员信息
            TbRidingBikePeopleExample tbRidingBikePeopleEx=new TbRidingBikePeopleExample();
            tbRidingBikePeopleEx.createCriteria().andBikeCommandEqualTo(command);
            delPeo=tbRidingBikePeopleMapper.deleteByExample(tbRidingBikePeopleEx);
            //删除车队
            TbRidingBikeExample tbRidingBikeExample=new TbRidingBikeExample();
            tbRidingBikeExample.createCriteria().andBikeCommandEqualTo(command);
            delBike=tbRidingBikeMapper.deleteByExample(tbRidingBikeExample);
            LOGGER.debug(delPeo+"------解散车队-------"+delBike);
        }
        if (delBike>0 && delPeo>0){
            return APIResponse.returnSuccess("解散车队成功");
        }else if (delPeo>0){
            return APIResponse.returnSuccess("退出车队成功");
        }else {
            return APIResponse.returnFail("退出车队失败");
        }
    }

    /**
     * 删除车队成员
     * @param leaderId
     * @param userId
     * @param command
     * @return
     */
    @Override
    @Transactional
    public APIResponse delRidingBikePeople(String leaderId, String userId,String command) {
        TbRidingBikePeopleExample tbRidingBikePeopleExample=new TbRidingBikePeopleExample();
        tbRidingBikePeopleExample.createCriteria().andBikeCommandEqualTo(command).andUserLimitEqualTo(Constans.BIKE_LEADER);
        List<TbRidingBikePeople> tbRidingBikePeopleList=tbRidingBikePeopleMapper.selectByExample(tbRidingBikePeopleExample);
        if (tbRidingBikePeopleList.size()==0){//车队的创建者不存在
            return APIResponse.returnFail(ApiResponseEnum.ILLEGAL_PROTOCOL);
        }
        TbRidingBikePeople tbRidingBikePeople=tbRidingBikePeopleList.get(0);
        if (!leaderId.equals(tbRidingBikePeople.getUserId())){//车队创建者与传过来的不一致，非法操作，
            return APIResponse.returnFail(ApiResponseEnum.ILLEGAL_PROTOCOL);
        }
        if (leaderId.equals(userId)){//创建者不能删除自己
            return APIResponse.returnFail(ApiResponseEnum.ILLEGAL_PROTOCOL);
        }
        //删除车队成员
        TbRidingBikePeopleExample delTbRidingBikePeople=new TbRidingBikePeopleExample();
        delTbRidingBikePeople.createCriteria().andBikeCommandEqualTo(command).andUserIdEqualTo(userId);
        int del=tbRidingBikePeopleMapper.deleteByExample(delTbRidingBikePeople);
        //车队成员数量-1
        int upd=myTbRidingRecordMapper.updateRidingBikePeople(command);
        if (del>0 && upd>0){
            return APIResponse.returnSuccess();
        }
        return APIResponse.returnFail("删除失败");
    }

    /**
     * 跟新车队公告
     * @param userId
     * @param command
     * @param notice
     * @return
     */
    @Override
    public APIResponse updateRidingBikeNotice(String userId,String command,String notice) {
        //根据口令查找车队信息
        TbRidingBikeExample tbRidingBikeExample=new TbRidingBikeExample();
        tbRidingBikeExample.createCriteria().andBikeCommandEqualTo(command);
        List<TbRidingBike> tbRidingBikeList=tbRidingBikeMapper.selectByExample(tbRidingBikeExample);
        if (tbRidingBikeList.size()==0){
            return APIResponse.returnFail(ApiResponseEnum.ILLEGAL_PROTOCOL);
        }
        TbRidingBike tbRidingBike=tbRidingBikeList.get(0);
        if (!tbRidingBike.getUserId().equals(userId)){//传过来的用户不是车队创建者
            return APIResponse.returnFail(ApiResponseEnum.ILLEGAL_PROTOCOL);
        }
        Map<String,Object> paramMap=new HashMap<>();
        paramMap.put("notice",notice);
        paramMap.put("command",command);
        int upde=myTbRidingRecordMapper.updateRidingBikeNotice(paramMap);
        if (upde>0){
            return APIResponse.returnSuccess();
        }
        return APIResponse.returnFail("跟新公告失败");
    }


}
